    
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <pthread.h>
#include "AaSysLog.h"


#define UDP_LOG_BYTE_PER_LINE       16


pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;


static char* log_level_str(ELevel_t level);


void AaSysLogInit(void)
{
    pthread_mutex_init(&log_mutex, NULL);
}

void AaSysLogPrintF(ELevel_t level, const char *funcname, const int line, const char* string, ...)
{
    va_list args;
    struct timeval tv; 
    struct tm *p_tm;

    gettimeofday(&tv, NULL);
    p_tm = localtime(&tv.tv_sec);

    pthread_mutex_lock(&log_mutex);

    printf("%04d-%02d-%02dT%02d:%02d:%02d.%06d [pid:%u][tid:%u] [%s] %s %d: ",  (1900 + p_tm->tm_year),    \
                                                                    ( 1 + p_tm->tm_mon),       \
                                                                    p_tm->tm_mday,             \
                                                                    p_tm->tm_hour,             \
                                                                    p_tm->tm_min,              \
                                                                    p_tm->tm_sec,              \
                                                                    (int)tv.tv_usec,        \
                                                                    (unsigned int)getpid(), \
                                                                    (unsigned int)pthread_self(),   \
                                                                    log_level_str(level), funcname, line );

    va_start(args, string);

    vprintf(string, args);

    va_end( args);

    printf("\n");

    pthread_mutex_unlock(&log_mutex);
}

void AaSysLogPrintD(char *data, int len)
{
    struct timeval tv; 
    struct tm *p_tm;
    int showlen;

    gettimeofday(&tv, NULL);
    p_tm = localtime(&tv.tv_sec);

    pthread_mutex_lock(&log_mutex);

    printf("%04d-%02d-%02dT%02d:%02d:%02d.%06d [pid:%u][tid:%u]: here is the memory dump:",  (1900 + p_tm->tm_year),    \
                                                                    ( 1 + p_tm->tm_mon),       \
                                                                    p_tm->tm_mday,             \
                                                                    p_tm->tm_hour,             \
                                                                    p_tm->tm_min,              \
                                                                    p_tm->tm_sec,              \
                                                                    (int)tv.tv_usec,        \
                                                                    (unsigned int)getpid(), \
                                                                    (unsigned int)pthread_self());

    while(showlen < len)
    {
        if ((showlen % UDP_LOG_BYTE_PER_LINE) == 0)
        {
            printf("\n%p: ", (data + showlen));
        }

        if ((showlen % UDP_LOG_BYTE_PER_LINE) == (UDP_LOG_BYTE_PER_LINE/2))
        {
            printf(" ");
        }

        printf(" %02x", (uint8_t)*(data + showlen));

        showlen++;
    }

    printf("\n");

    pthread_mutex_unlock(&log_mutex);
}

static char* log_level_str(ELevel_t level)
{
    switch(level)
    {
        case Debug: return "DBG";
        case Info: return "INF";
        case Warning: return "WRN";
        case Error: return "ERR";
        case VIP: return "VIP";
        default: return "None";
    }
}
